package indi.zhifa.recipe.bailan.framework.auth.memo;

import cn.hutool.core.util.ClassUtil;
import indi.zhifa.recipe.bailan.framework.auth.entity.dto.auth.TableAuthColumn;
import indi.zhifa.recipe.bailan.framework.auth.entity.dto.auth.TableAuthMapItem;
import indi.zhifa.recipe.bailan.framework.auth.entity.annotations.auth.TableAuth;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

@Slf4j
@Component
public class MapperAuthMapMemo {
    private final Map<String, TableAuthMapItem> mMapperAuthMap;
    public MapperAuthMapMemo(){
        mMapperAuthMap = new HashMap<>();
    }
    public void put(String pClsName, TableAuthMapItem pTableAuthMapItem){
        mMapperAuthMap.put(pClsName,pTableAuthMapItem);
    }
    public TableAuthMapItem loadClass(String pMappedStatementId){
        int lastDotIdx = pMappedStatementId.lastIndexOf('.');
        String clsName = pMappedStatementId.substring(0,lastDotIdx);
        TableAuthMapItem tableAuthMapItem = mMapperAuthMap.get(clsName);
        if(null == tableAuthMapItem){
            tableAuthMapItem = new TableAuthMapItem();
            mMapperAuthMap.put(clsName,tableAuthMapItem);
            Class<Object> mapperCls = ClassUtil.loadClass(clsName);
            TableAuth annotation = mapperCls.getAnnotation(TableAuth.class);
            if(null != annotation){
                tableAuthMapItem.setTableAuth(annotation);
                tableAuthMapItem.setExist(true);
                boolean hasError = !testTableAuth(clsName,annotation);
                tableAuthMapItem.setError(hasError);
                if(!hasError){
                    Map<String, TableAuthColumn> tableAuthColumnMap = getTableAuthColumnMap(clsName,annotation);
                    tableAuthMapItem.setTableAuthColumnsMap(tableAuthColumnMap);
                }
                tableAuthMapItem.setRelUserColumnName(annotation.relUserIdColumn());
            }else{
                tableAuthMapItem.setTableAuth(null);
                tableAuthMapItem.setExist(false);
            }
        }
        return tableAuthMapItem;
    }

    private boolean testTableAuth(String pClsName, TableAuth pTableAuth){
        String[] domains = pTableAuth.domains();
        String[] idColumns = pTableAuth.idColumns();
        String[] cascadeColumns = pTableAuth.cascadeColumns();
        if(null != domains && domains.length > 0){
            if(null == idColumns){
                log.error(pClsName+"没有配置idColumns");
                return false;
            }
            if(null == cascadeColumns){
                log.error(pClsName+"没有配置cascadeColumns");
                return false;
            }
            if(domains.length!= idColumns.length){
                log.error(pClsName+"idColumns长度与domains不同");
                return false;
            }
            if(domains.length!= cascadeColumns.length){
                log.error(pClsName+"cascadeColumns长度与domains不同");
                return false;
            }
        }
        return true;
    }
    private Map<String, TableAuthColumn> getTableAuthColumnMap(String pClsName, TableAuth pTableAuth){
        String[] domains = pTableAuth.domains();
        String[] idColumns = pTableAuth.idColumns();
        String[] cascadeColumns = pTableAuth.cascadeColumns();
        Map<String, TableAuthColumn> rtn = new HashMap<>();
        for(int i=0;i<domains.length;i++){
            TableAuthColumn tableAuthColumn = new TableAuthColumn();
            tableAuthColumn.setIdColumn(idColumns[i]);
            tableAuthColumn.setCascadeColumn(cascadeColumns[i]);
            String domain = domains[i];
            rtn.put(domain, tableAuthColumn);
        }
        return rtn;
    }

}
